/* $Header: p_ctrl.c,v 2.2 01/10/02 10:27:48 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:   Pneumatics Control                                   */
/* ============                                                        */
/*                                                                     */
/* Author:  wikfors                                                    */
/*                                                                     */
/* MODULE PURPOSE: high level pneumatics control functions.            */
/*                 calculate pressure and flow setpts for each pneu ch.*/
/*                 send to the dsp.                                    */
/*                 set split/splitless mode/valves to correct states   */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/


#include <typedefs.h>
#include <error.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <i_op.h>
#include <p_status.h>
#include <ramps.h>
#include <zone_config.h>
#include <zone_status.h>
#include <status.h>
#include <list_mgmt.h>
#include <regs.h>
#include <keyboard.h>

/* the following are to use SetException */
#include <exception.h>
#include <err_handler.h>
/*------begin changed by wangwei----------------*/
#include <sys/time.h>
/*------end changed by wangwei------------------*/
/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "proto.h"

#define pFRONT_INLET        GetFrontInletPtr()
#define pBACK_INLET         GetBackInletPtr()

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


        BIT8 Valve_On_Off_Mask;

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/


/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/**begin_proto**/

void InitSolenoidValveDrive(void)

/**end_proto**/
{
    Valve_On_Off_Mask = ~0;
}


/***********************************************************************/
/* FUNCTION: PneuControl                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:   Perform Primary control operations                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void NonEpcPneuControl(void)

/**end_proto**/
{

     if ( Inst_Status.Pneu.What_Now == DO_AUXES ) Inst_Status.Pneu.What_Now = DO_FRNT_INLET;
     else                                         Inst_Status.Pneu.What_Now++;

     switch ( Inst_Status.Pneu.What_Now )
     {

       case DO_FRNT_INLET:  if ( Inst_Config.Pneu.Frnt_Inlet.Type == MANUAL_SS )
                            {
                                ManualSplitSplitless( &Inst_Status.Pneu.Frnt_Inlet );
                            }
                            CheckInletReadiness ( &Inst_Status.Pneu.Frnt_Inlet );
                            break;

       case DO_BACK_INLET: if ( Inst_Config.Pneu.Back_Inlet.Type == MANUAL_SS )
                           {
                                ManualSplitSplitless( &Inst_Status.Pneu.Back_Inlet );
                           }
                           CheckInletReadiness ( &Inst_Status.Pneu.Back_Inlet );
                           break;

       case DO_FRNT_DET:   CheckDetectorReadiness ( &Inst_Status.Pneu.Frnt_Detector );
                           break;


       case DO_BACK_DET:  CheckDetectorReadiness ( &Inst_Status.Pneu.Back_Detector );
                          break;

       case DO_AUXES:     CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_3 );
                          CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_4 );
                          CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_5 );
                          break;

       default:           /* catch any strange initialization of What_Now */
                          Inst_Status.Pneu.What_Now = DO_FRNT_INLET;

     } /* switch what now */

}


/***********************************************************************/
/* FUNCTION: PneuControl                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:   Perform Primary control operations                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void PneuControl(void)

/**end_proto**/
{
     U_INT8 ctr_8khz;
     U_INT8 out_ctr_8khz;
     U_INT32 time_this_invocation;
static U_INT8 ctr;
static U_INT32 sum;
static U_INT16 environment_counter = 1;
/*------------begin changed by wangwei-------------*/
    struct timeval start;
    struct timeval end;
/*------------end   changed by wangwei-------------*/

     /* if i can't get exclusive access to setpoints, skip out */

     if ( IsrLockResource( &Inst_Status.Pneu.Resource_Lock ) == FALSE )
     {
          if ( Run_State == RUN_ACTIVE )
          {
              /* SetException( ); */
          }
          return;
     }

     if ( Inst_Status.Pneu.Block_Foreground_Interrupts )
     {
          INTERRUPTS_OFF;
     }

/*------------begin changed by wangwei-------------*/
//     ctr_8khz = *(U_INT8 *)PACNT;
//     gettimeofday(&start,NULL);
/*------------end   changed by wangwei-------------*/

     if ( environment_counter-- == 0 )
     {
          environment_counter = Inst_Status.Pneu.Environment_Freq;  /* once every 5 Seconds */
          PeriodicPresCorrect ();
     }


     /* schedule the background tasks so that there returns are handled */
     /* during a detector cycle. this evens out the peak load.          */

     if ((environment_counter <   5) &&
         ( Inst_Status.Pneu.What_Now == DO_BACK_INLET ))  RequestEnvironment();

     if ((environment_counter >=  5) &&
         (environment_counter <  10) &&
         ( Inst_Status.Pneu.What_Now == DO_BACK_INLET ))  RequestICapCounters();

     if ((environment_counter >= 10) &&
         (environment_counter <  15) &&
         ( Inst_Status.Pneu.What_Now == DO_BACK_INLET ))  ForegroundReadDutyCycles();


     if ( Inst_Status.Pneu.What_Now == DO_AUXES ) Inst_Status.Pneu.What_Now = DO_FRNT_INLET;
     else                                         Inst_Status.Pneu.What_Now++;


     switch ( Inst_Status.Pneu.What_Now )
     {

           /********************************************************/
           /*                                                      */
           /*  C O N T R O L    T H E    F R O N T    I N L E T    */
           /*                                                      */
           /*                                                      */
           /********************************************************/

           case DO_FRNT_INLET:

           if (( !Inst_Config.Pneu.Frnt_Inlet.Functional )           ||
               ( Active_Wkfile.Pneu.Frnt_Inlet.On_Off == OFF ))
           {
                 Inst_Status.Pneu.Frnt_Inlet.Pres_Adc_Setpt = 0;
                 Inst_Status.Pneu.Frnt_Inlet.Flow_Adc_Setpt = 0;
                 Inst_Status.Pneu.Frnt_Inlet.Ready.Pres.Controlled = FALSE;
                 Inst_Status.Pneu.Frnt_Inlet.Ready.Flow.Controlled = FALSE; }
           else
           {

                 if ( !DoingMethodInstall() )
                 {
                     switch ( Inst_Config.Pneu.Frnt_Inlet.Type )
                     {
                        case SS: SplitSplitless( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case PTV: PTVInlet( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case COC: CoolOnColumn(  &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case PP:  PurgedPacked( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case ACI: PurgedPacked( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case SIMDIST:
                                  PurgedPacked( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case CIS3 :
                        case CIS4 :
                                  GerstelPTV( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case JIB: JackInTheBox( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case VOLATILES:
                                  Volatiles( &Inst_Status.Pneu.Frnt_Inlet );
                                  break;

                        case MANUAL_COC:
                        case MANUAL_ACI:
                        case MANUAL_PP:  Inst_Status.Pneu.Frnt_Inlet.Pres_Adc_Setpt = 0;
                                         Inst_Status.Pneu.Frnt_Inlet.Flow_Adc_Setpt = 0;
                                         break;

                        case MANUAL_SS: ManualSplitSplitless( &Inst_Status.Pneu.Frnt_Inlet );
                                        break;

                        default: ;
                     }
                 }
           }

           CheckInletReadiness ( &Inst_Status.Pneu.Frnt_Inlet );

           break;

           /********************************************************/
           /*                                                      */
           /*  C O N T R O L    T H E     B A C K     I N L E T    */
           /*                                                      */
           /*                                                      */
           /********************************************************/

           case DO_BACK_INLET:

           if (( !Inst_Config.Pneu.Back_Inlet.Functional )           ||
               ( Active_Wkfile.Pneu.Back_Inlet.On_Off == OFF ))
           {
                 Inst_Status.Pneu.Back_Inlet.Pres_Adc_Setpt = 0;
                 Inst_Status.Pneu.Back_Inlet.Flow_Adc_Setpt = 0;
                 Inst_Status.Pneu.Back_Inlet.Ready.Pres.Controlled = FALSE;
                 Inst_Status.Pneu.Back_Inlet.Ready.Flow.Controlled = FALSE; }
           else
           {
                 if ( !DoingMethodInstall() )
                 {
                     switch ( Inst_Config.Pneu.Back_Inlet.Type )
                     {
                        case SS:  SplitSplitless( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case PTV: PTVInlet( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case COC: CoolOnColumn( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case PP:  PurgedPacked( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case ACI: PurgedPacked( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case SIMDIST:
                                  PurgedPacked( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case CIS3 :
                        case CIS4 :
                                  GerstelPTV( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case JIB: JackInTheBox( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case VOLATILES :
                                  Volatiles( &Inst_Status.Pneu.Back_Inlet );
                                  break;

                        case MANUAL_COC:
                        case MANUAL_ACI:
                        case MANUAL_PP:  Inst_Status.Pneu.Back_Inlet.Pres_Adc_Setpt = 0;
                                         Inst_Status.Pneu.Back_Inlet.Flow_Adc_Setpt = 0;
                                         break;

                        case MANUAL_SS: ManualSplitSplitless( &Inst_Status.Pneu.Back_Inlet );
                                        break;
                        default: ;
                     }
                 }
           }

           CheckInletReadiness ( &Inst_Status.Pneu.Back_Inlet );

           break;

           /********************************************************/
           /*                                                      */
           /* C O N T R O L  T H E   F R O N T   D E T C E C T O R */
           /*                                                      */
           /*                                                      */
           /********************************************************/

           case DO_FRNT_DET:

           if ((!EpcDetector(&Inst_Status.Pneu.Frnt_Detector))          ||
               (Inst_Status.Pneu.Frnt_Detector.Shutdown == TRUE ))
           {
                 Inst_Status.Pneu.Frnt_Detector.Gas_1.Adc_Setpt = 0;
                 Inst_Status.Pneu.Frnt_Detector.Gas_2.Adc_Setpt = 0;
                 Inst_Status.Pneu.Frnt_Detector.Gas_3.Adc_Setpt = 0;
           }
           else
           {
                 if ( !DoingMethodInstall() ) DoDetGases(&Inst_Status.Pneu.Frnt_Detector );
           }

           CheckDetectorReadiness ( &Inst_Status.Pneu.Frnt_Detector );

           break;


           /********************************************************/
           /*                                                      */
           /* C O N T R O L  T H E    B A C K    D E T C E C T O R */
           /*                                                      */
           /*                                                      */
           /********************************************************/

           case DO_BACK_DET:

           if ((!EpcDetector(&Inst_Status.Pneu.Back_Detector))          ||
               (Inst_Status.Pneu.Back_Detector.Shutdown == TRUE ))
           {
                 Inst_Status.Pneu.Back_Detector.Gas_1.Adc_Setpt = 0;
                 Inst_Status.Pneu.Back_Detector.Gas_2.Adc_Setpt = 0;
                 Inst_Status.Pneu.Back_Detector.Gas_3.Adc_Setpt = 0;
           }
           else
           {
                 if ( !DoingMethodInstall() ) DoDetGases(&Inst_Status.Pneu.Back_Detector );
           }


           CheckDetectorReadiness ( &Inst_Status.Pneu.Back_Detector );

           break;

           /********************************************************/
           /*                                                      */
           /*     C O N T R O L    A U X   3                       */
           /*                                                      */
           /*                                                      */
           /********************************************************/

           case DO_AUXES:

         if (( !Inst_Config.Pneu.Aux_3.Functional )         ||
             ( Inst_Status.Pneu.Aux.Aux_3.On_Off == OFF )   ||
             ( Inst_Status.Pneu.Aux.Aux_3.Shutdown == TRUE ))
         {
              Inst_Status.Pneu.Aux.Aux_3.Adc_Setpt = 0;
         }
         else
         {
             if ( !DoingMethodInstall() ) ControlAux( &Inst_Status.Pneu.Aux.Aux_3, &Inst_Status.Pneu.Aux );
         }

         CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_3 );

           /********************************************************/
           /*                                                      */
           /*     C O N T R O L    A U X   4                       */
           /*                                                      */
           /*                                                      */
           /********************************************************/

         if (( !Inst_Config.Pneu.Aux_4.Functional )         ||
             ( Inst_Status.Pneu.Aux.Aux_4.On_Off == OFF )   ||
             ( Inst_Status.Pneu.Aux.Aux_4.Shutdown == TRUE ))
         {
              Inst_Status.Pneu.Aux.Aux_4.Adc_Setpt = 0;
         }
         else
         {
             if ( !DoingMethodInstall() ) ControlAux( &Inst_Status.Pneu.Aux.Aux_4, &Inst_Status.Pneu.Aux );
         }

         CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_4 );

           /********************************************************/
           /*                                                      */
           /*     C O N T R O L    A U X   5                       */
           /*                                                      */
           /*                                                      */
           /********************************************************/

         if (( !Inst_Config.Pneu.Aux_5.Functional )         ||
             ( Inst_Status.Pneu.Aux.Aux_5.On_Off == OFF )   ||
             ( Inst_Status.Pneu.Aux.Aux_5.Shutdown == TRUE ))
         {
              Inst_Status.Pneu.Aux.Aux_5.Adc_Setpt = 0;
         }
         else
         {
             if ( !DoingMethodInstall() ) ControlAux( &Inst_Status.Pneu.Aux.Aux_5, &Inst_Status.Pneu.Aux );
         }

         CheckAuxReadiness ( &Inst_Status.Pneu.Aux.Aux_5 );
         break;


         default:  /* catch any strange initialization of What_Now */
              Inst_Status.Pneu.What_Now = DO_FRNT_INLET;

     } /* switch what now */

     DownloadSetpoints();

     ReleaseResource( &Inst_Status.Pneu.Resource_Lock );

/*------------begin changed by wangwei-------------*/
//     gettimeofday(&end,NULL);
     time_this_invocation = 0;//1000000*(end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
//     time_this_invocation = 10000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec)/100;

//      printf("time:%d:exit\n",time_this_invocation );
//     out_ctr_8khz = *(U_INT8 *)PACNT;
//     if ( out_ctr_8khz < ctr_8khz)
//     {
//          time_this_invocation = (1 + out_ctr_8khz + ( 0xff - ctr_8khz ) ) * 125;
//     }
//     else
//     {
//          time_this_invocation = ( 1 + out_ctr_8khz - ctr_8khz ) * 125;
//     }
/*------------end   changed by wangwei-------------*/
     if ( ctr-- == 0 )
     {
         Inst_Status.Pneu.Avg_Ctrl_Time = sum / 250;
         ctr = 250;
         sum = 0;
     }
     else
     {
         sum += time_this_invocation;
     }


     if ( Inst_Status.Pneu.Peak_Ctrl_Time < time_this_invocation ) Inst_Status.Pneu.Peak_Ctrl_Time = time_this_invocation
;

     if ( Inst_Status.Pneu.Block_Foreground_Interrupts )
     {
         INTERRUPTS_ON;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void SolenoidValveDrive(void)

/**end_proto**/
{

     static U_INT16 Frnt_Local_Demand;
     static U_INT16 Back_Local_Demand;

     static U_INT16 Frnt_State;
     static U_INT16 Back_State;

     BIT8   valve_mask;

     valve_mask = 0;


     ClearNewException ( PNEU_24_VOLTS );

     if ( Inst_Status.Pneu.Frnt_Inlet.Diag_Mode_Enabled  )
     {
         if ( Inst_Status.Pneu.Frnt_Inlet.Solenoid_Valve_Enable ) valve_mask |=  0x08;
     }
     else
     {
         /* alway on when "x" OR "y" OR ... OR  shutdown (!)  */
         if (
             (
               Inst_Status.Pneu.Frnt_Inlet.Inlet_Purge &&
               Inst_Config.Pneu.Frnt_Inlet.Functional  && ( Active_Wkfile.Pneu.Frnt_Inlet.On_Off == ON  ) &&
               ( ( VIGetInletType(pFRONT_INLET) == SS ) || (Inst_Config.Pneu.Frnt_Inlet.Type == CIS3  ) ||
                 ( Inst_Config.Pneu.Frnt_Inlet.Type == CIS4  )
               )
             )
             ||
         /*  ( ( (U_INT16)FIName[2] & 1) && ( Active_Wkfile.Pneu.Frnt_Inlet.Injection_Mode == DIRECT ) ) */
             (  Active_Wkfile.Pneu.Frnt_Inlet.Injection_Mode == DIRECT  )
                                                                    /* force split vent OPEN to ensure cap is in place */
             ||
             Inst_Status.Pneu.Frnt_Inlet.Shutdown
            )
            valve_mask |=  0x08;
     }

     if ( Inst_Status.Pneu.Back_Inlet.Diag_Mode_Enabled  )
     {
         if ( Inst_Status.Pneu.Back_Inlet.Solenoid_Valve_Enable ) valve_mask |=  0x80;
     }
     else
     {
         if (
             (
              Inst_Status.Pneu.Back_Inlet.Inlet_Purge &&
              Inst_Config.Pneu.Back_Inlet.Functional  && ( Active_Wkfile.Pneu.Back_Inlet.On_Off == ON  ) &&
              ( ( VIGetInletType(pBACK_INLET) == SS ) || (Inst_Config.Pneu.Back_Inlet.Type == CIS3 ) ||
                ( Inst_Config.Pneu.Back_Inlet.Type == CIS4 )
              )
             )
             ||
         /*  ( ( (U_INT16)BIName[2] & 1) && ( Active_Wkfile.Pneu.Back_Inlet.Injection_Mode == DIRECT ) ) */
             ( Active_Wkfile.Pneu.Back_Inlet.Injection_Mode == DIRECT   )
                                                                    /* force split vent OPEN to ensure cap is in place */
             ||
             Inst_Status.Pneu.Back_Inlet.Shutdown
            )
            valve_mask |=  0x80;
     }


     if ( !EpcDetector ( &Inst_Status.Pneu.Frnt_Detector ) )
     {
          if ( Inst_Status.Pneu.Frnt_Detector.Gas_1.On_Off )     valve_mask |= 0x01;
          if ( Inst_Status.Pneu.Frnt_Detector.Gas_2.On_Off )     valve_mask |= 0x02;
          if ( Inst_Status.Pneu.Frnt_Detector.Gas_3.On_Off )     valve_mask |= 0x04;
     }

     if ( !EpcDetector ( &Inst_Status.Pneu.Back_Detector ) )
     {
          if ( Inst_Status.Pneu.Back_Detector.Gas_1.On_Off )     valve_mask |= 0x10;
          if ( Inst_Status.Pneu.Back_Detector.Gas_2.On_Off )     valve_mask |= 0x20;
          if ( Inst_Status.Pneu.Back_Detector.Gas_3.On_Off )     valve_mask |= 0x40;
     }



   if (( Inst_Status.Pneu.Frnt_Detector.In_Ignition_Sequence ) &&
       ( Inst_Status.Pneu.Frnt_Detector.Duty_Cycle != 0 ))
   {
       if ( Frnt_State >= 100 )  /* 50Hz rate, .5Hz desired = 100 tics */
       {
            Frnt_State = 0;
            Frnt_Local_Demand = Inst_Status.Pneu.Frnt_Detector.Duty_Cycle;
       }

       if ( Frnt_State++ < Frnt_Local_Demand )  /* valve should be on */
       {
            switch ( Inst_Status.Pneu.Frnt_Detector.Modulated_Gas )
            {
                 case 1:  valve_mask |= 0x01;
                          break;
                 case 2:  valve_mask |= 0x02;
                          break;
                 case 3:  valve_mask |= 0x04;
                          break;
            }
       }
       else  /* valve should be off */
       {
            switch ( Inst_Status.Pneu.Frnt_Detector.Modulated_Gas )
            {
                 case 1:  valve_mask &= ~0x01;
                          break;
                 case 2:  valve_mask &= ~0x02;
                          break;
                 case 3:  valve_mask &= ~0x04;
                          break;
            }
       }
   }





   if (( Inst_Status.Pneu.Back_Detector.In_Ignition_Sequence ) &&
       ( Inst_Status.Pneu.Back_Detector.Duty_Cycle != 0 ))
   {
       if ( Back_State >= 100 )  /* 50Hz rate, .5Hz desired = 100 tics */
       {
            Back_State = 0;
            Back_Local_Demand = Inst_Status.Pneu.Back_Detector.Duty_Cycle;
       }

       if ( Back_State++ < Back_Local_Demand )
       {
            switch ( Inst_Status.Pneu.Back_Detector.Modulated_Gas )
            {
                 case 1:  valve_mask |= 0x10;
                          break;
                 case 2:  valve_mask |= 0x20;
                          break;
                 case 3:  valve_mask |= 0x40;
                          break;
            }
       }
       else
       {
            switch ( Inst_Status.Pneu.Back_Detector.Modulated_Gas )
            {
                 case 1:  valve_mask &= ~0x10;
                          break;
                 case 2:  valve_mask &= ~0x20;
                          break;
                 case 3:  valve_mask &= ~0x40;
                          break;
            }
       }
   }




   Valve_On_Off_Mask =   ~valve_mask;

}
